#include "Dispatch.h"
#include "Reactor.h"
#include "ServerConn.h"
#include "Listener.h"
#include "../Defind.h"
#include "Socket.h"
#include "ThreadPool.h"

#include <iostream>
#include <functional>
#include <thread>

using namespace DBServer::Socket;


int server_init(std::function<std::string(std::string&&)> logic_func, 
                std::string&& ip, int port)
{
    // thread pool
    ThreadPool::GetInstance()->work();

    // Listener
    Listener *listener = new Listener();
    listener->set_socket_info(std::move(ip), port);
    listener->create_socket();
    socket_set_reuse(*listener);
    socket_set_unblock(*listener);

    // Dispatch
    Dispatch *dispatch = new Dispatch(*listener);

    // Reactor
    std::vector<Reactor*> ReactorMap;
    std::vector<std::thread> thread_list;
    for (int i = 0; i < REACTOR_NUM; i++)
    {
        Reactor *reactor = new Reactor();
        ReactorMap.push_back(reactor);
        // register in dispatch
        dispatch->reactor_reg(reactor);
    }
    for (int i = 0; i < REACTOR_NUM; i++)
    {
        auto reactor = ReactorMap[i];
        // run the reactor
        thread_list.emplace_back([reactor]{
            int ret =reactor->run();
            if (ret == -1)
            {
                std::cerr << "[error]\n";
                std::cerr << std::this_thread::get_id() << std::endl;
            }
        });
    }
    
    // run dispatch
    dispatch->run(logic_func); 

    // signal handle to stop the server
}


#if 1

#include <cstdlib>

std::string logic(std::string&& s) 
{
    std::string _s("accept");
    return s;
}

int main(int argc, char **argv) {
    if (argc < 2) {
        std::cout << "error" << std::endl;
        exit(1);
    }
    std::string ip(argv[1]);
    int port = atoi(argv[2]);
    std::thread t(server_init, logic, std::move(ip), port);
    while(true) {}
    t.join();
}


#endif